﻿using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Basedatas;
using mozhi.smarterp.Finance.Basedatas.Suppliers;
using mozhi.smarterp.Finance.Enums;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;

namespace mozhi.smarterp.Finance.Ieps.Import
{
    public class SupplierImportHandler : ImportHandlerBase<SupplierDto>
    {
        private IAccountRepository _accountRepository;

        private ISupplierAppService _supplierAppService;

        public SupplierImportHandler(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _accountRepository = serviceProvider.GetService(typeof(IAccountRepository)) as IAccountRepository;
            _supplierAppService = serviceProvider.GetService(typeof(ISupplierAppService)) as ISupplierAppService;
        }

        public override async Task<ImportResultDto> HandleImportData(Guid fileId)
        {
            var suppliers = (await GetImportData(ModuleCodeType.Supplier, fileId)) as List<SupplierDto>;

            await LoadAccountsAsync(suppliers);

            var result = new ImportResultDto();

            result.Total = suppliers.Count;

            result.Errors = new List<string>();

            //开始上传供应商
            for (int i = 0; i < suppliers.Count; i++)
            {
                var supplier = suppliers[i];

                var createDto = new SupplierCreateDto();
                createDto.Name = supplier.Name;
                createDto.Code = supplier.Code;
                createDto.PayableAccountId = supplier.PayableAccountId;
                createDto.PrepaymentAccountId = supplier.PrepaymentAccountId;

                try
                {
                    await _supplierAppService.CreateAsync(createDto);
                    result.SuccessfulCount += 1;
                }
                catch (UserFriendlyException ex)
                {
                    result.FailureCount += 1;
                    result.Errors.Add($"第{i + 1}行有错误：{ex.Message}");
                }
            }

            return result;
        }


        protected override List<SupplierDto> ConvertToData(DataSet ds)
        {
            var result = new List<SupplierDto>();

            var dt = ds.Tables[0];

            if(dt.Rows.Count==0)
                return result;

            foreach(DataRow row in dt.Rows)
            {
                var supplier = new SupplierDto();
                supplier.Code = row["Code"].ToString();
                supplier.Name = row["Name"].ToString();
                supplier.PayableAccountName = row["PayableAccountName"].ToString();
                supplier.PrepaymentAccountName = row["PrepaymentAccountName"].ToString();

                result.Add(supplier);
            }

            return result;
        }

        #region
        private async Task LoadAccountsAsync(List<SupplierDto> suppliers)
        {
            var accountNames = suppliers.Where(x => x.PayableAccountName != null).Select(x => x.PayableAccountName).Distinct().ToList();

            accountNames.AddRange(suppliers.Where(x => x.PrepaymentAccountName != null).Select(x => x.PrepaymentAccountName).Distinct().ToList());

            var accountCodes = new List<string>();

            foreach(var accountName in accountNames)
            {
                var splits = accountName.Split(' ');

                accountCodes.Add(splits[0]);
            }

            var accounts = await _accountRepository.FindAsync(new Querys.AccountQuery() { Codes = accountCodes });

            if (accounts.Count == 0)
                return;

            foreach(var suplier in suppliers)
            {
                if (!suplier.PayableAccountName.IsNullOrEmpty())
                {
                    var splits = suplier.PayableAccountName.Split(' ');

                    var matchAccount = accounts.FirstOrDefault(x => x.Code == splits[0] || x.Name == splits[0]);

                    suplier.PayableAccountId = matchAccount==null ? default : matchAccount.Id;
                }

                if (!suplier.PrepaymentAccountName.IsNullOrEmpty())
                {
                    var splits = suplier.PrepaymentAccountName.Split(' ');

                    var matchAccount = accounts.FirstOrDefault(x => x.Code == splits[0] || x.Name == splits[0]);

                    suplier.PrepaymentAccountId = matchAccount == null ? default : matchAccount.Id;
                }
            }
        }
        #endregion
    }
}
